package com.ruoyi.project.system.service.impl

import com.ruoyi.common.constant.UserConstants
import com.ruoyi.common.exception.ServiceException
import com.ruoyi.common.utils.SecurityUtils
import com.ruoyi.common.utils.StringUtils
import com.ruoyi.common.utils.spring.SpringUtils
import com.ruoyi.framework.aspectj.lang.annotation.DataScope
import com.ruoyi.project.system.domain.*
import com.ruoyi.project.system.mapper.SysRoleDeptMapper
import com.ruoyi.project.system.mapper.SysRoleMapper
import com.ruoyi.project.system.mapper.SysRoleMenuMapper
import com.ruoyi.project.system.mapper.SysUserRoleMapper
import com.ruoyi.project.system.service.ISysRoleService
import org.springframework.beans.factory.annotation.Autowired
import org.springframework.stereotype.Service
import org.springframework.transaction.annotation.Transactional


/**
 * 角色 业务层处理
 *
 * @author ruoyi
 */
@Service
class SysRoleServiceImpl : ISysRoleService {
    @Autowired
    private val roleMapper: SysRoleMapper? = null

    @Autowired
    private val roleMenuMapper: SysRoleMenuMapper? = null

    @Autowired
    private val userRoleMapper: SysUserRoleMapper? = null

    @Autowired
    private val roleDeptMapper: SysRoleDeptMapper? = null

    /**
     * 根据条件分页查询角色数据
     *
     * @param role 角色信息
     * @return 角色数据集合信息
     */
    @DataScope(deptAlias = "d")
    override fun selectRoleList(role: SysRole?): List<SysRole>? {
        return roleMapper!!.selectRoleList(role)
    }

    /**
     * 根据用户ID查询角色
     *
     * @param userId 用户ID
     * @return 角色列表
     */
    override fun selectRolesByUserId(userId: Long?): List<SysRole> {
        val userRoles = roleMapper!!.selectRolePermissionByUserId(userId)
        val roles = selectRoleAll()!!
        roles.filter { role -> userRoles.any { role.roleId == it!!.roleId } }.forEach { it.isFlag = true }
        return roles
    }

    /**
     * 根据用户ID查询权限
     *
     * @param userId 用户ID
     * @return 权限列表
     */
    override fun selectRolePermissionByUserId(userId: Long?): Set<String> {
        val perms = roleMapper!!.selectRolePermissionByUserId(userId)
        return perms.filterNotNull().flatMap { it.roleKey!!.trim().split(",".toRegex()) }.toSet()
    }

    /**
     * 查询所有角色
     *
     * @return 角色列表
     */
    override fun selectRoleAll(): List<SysRole>? {
        return SpringUtils.getAopProxy(this).selectRoleList(SysRole())
    }

    /**
     * 根据用户ID获取角色选择框列表
     *
     * @param userId 用户ID
     * @return 选中角色ID列表
     */
    override fun selectRoleListByUserId(userId: Long?): List<Long?>? {
        return roleMapper!!.selectRoleListByUserId(userId)
    }

    /**
     * 通过角色ID查询角色
     *
     * @param roleId 角色ID
     * @return 角色对象信息
     */
    override fun selectRoleById(roleId: Long?): SysRole {
        return roleMapper!!.selectRoleById(roleId)!!
    }

    /**
     * 校验角色名称是否唯一
     *
     * @param role 角色信息
     * @return 结果
     */
    override fun checkRoleNameUnique(role: SysRole): String? {
        val roleId = if (StringUtils.isNull(role.roleId)) -1L else role.roleId
        val info = roleMapper!!.checkRoleNameUnique(role.roleName)
        return if (StringUtils.isNotNull(info) && info!!.roleId!! != roleId!!) {
            UserConstants.NOT_UNIQUE
        } else UserConstants.UNIQUE
    }

    /**
     * 校验角色权限是否唯一
     *
     * @param role 角色信息
     * @return 结果
     */
    override fun checkRoleKeyUnique(role: SysRole): String? {
        val roleId = if (StringUtils.isNull(role.roleId)) -1L else role.roleId
        val info = roleMapper!!.checkRoleKeyUnique(role.roleKey)
        return if (StringUtils.isNotNull(info) && info!!.roleId!! != roleId) {
            UserConstants.NOT_UNIQUE
        } else UserConstants.UNIQUE
    }

    /**
     * 校验角色是否允许操作
     *
     * @param role 角色信息
     */
    override fun checkRoleAllowed(role: SysRole) {
        if (StringUtils.isNotNull(role.roleId) && role.isAdmin) {
            throw ServiceException("不允许操作超级管理员角色")
        }
    }

    /**
     * 校验角色是否有数据权限
     *
     * @param roleId 角色id
     */
    override fun checkRoleDataScope(roleId: Long?) {
        if (!SysUser.isAdmin(SecurityUtils.getUserId())) {
            val role = SysRole()
            role.roleId = roleId
            val roles = SpringUtils.getAopProxy(this).selectRoleList(role)
            if (StringUtils.isEmpty(roles)) {
                throw ServiceException("没有权限访问角色数据！")
            }
        }
    }

    /**
     * 通过角色ID查询角色使用数量
     *
     * @param roleId 角色ID
     * @return 结果
     */
    override fun countUserRoleByRoleId(roleId: Long?): Int {
        return userRoleMapper!!.countUserRoleByRoleId(roleId)
    }

    /**
     * 新增保存角色信息
     *
     * @param role 角色信息
     * @return 结果
     */
    @Transactional
    override fun insertRole(role: SysRole): Int {
        // 新增角色信息
        roleMapper!!.insertRole(role)
        return insertRoleMenu(role)
    }

    /**
     * 修改保存角色信息
     *
     * @param role 角色信息
     * @return 结果
     */
    @Transactional
    override fun updateRole(role: SysRole): Int {
        // 修改角色信息
        roleMapper!!.updateRole(role)
        // 删除角色与菜单关联
        roleMenuMapper!!.deleteRoleMenuByRoleId(role.roleId)
        return insertRoleMenu(role)
    }

    /**
     * 修改角色状态
     *
     * @param role 角色信息
     * @return 结果
     */
    override fun updateRoleStatus(role: SysRole?): Int {
        return roleMapper!!.updateRole(role)
    }

    /**
     * 修改数据权限信息
     *
     * @param role 角色信息
     * @return 结果
     */
    @Transactional
    override fun authDataScope(role: SysRole): Int {
        // 修改角色信息
        roleMapper!!.updateRole(role)
        // 删除角色与部门关联
        roleDeptMapper!!.deleteRoleDeptByRoleId(role.roleId)
        // 新增角色和部门信息（数据权限）
        return insertRoleDept(role)
    }

    /**
     * 新增角色菜单信息
     *
     * @param role 角色对象
     */
    private fun insertRoleMenu(role: SysRole): Int {
        // 新增用户与角色管理
        val list: MutableList<SysRoleMenu> = ArrayList()
        role.menuIds!!.forEach {
            val rm = SysRoleMenu()
            rm.roleId = role.roleId
            rm.menuId = it
            list.add(rm)
        }
        return if (list.size > 0) {
            roleMenuMapper!!.batchRoleMenu(list)
        } else {
            1
        }
    }

    /**
     * 新增角色部门信息(数据权限)
     *
     * @param role 角色对象
     */
    private fun insertRoleDept(role: SysRole): Int {
        // 新增角色与部门（数据权限）管理
        val list: MutableList<SysRoleDept> = ArrayList()
        role.deptIds!!.forEach {
            val rd = SysRoleDept()
            rd.roleId = role.roleId
            rd.deptId = it
            list.add(rd)
        }
        return if (list.size > 0) {
            roleDeptMapper!!.batchRoleDept(list)
        } else {
            1
        }
    }

    /**
     * 通过角色ID删除角色
     *
     * @param roleId 角色ID
     * @return 结果
     */
    @Transactional
    override fun deleteRoleById(roleId: Long?): Int {
        // 删除角色与菜单关联
        roleMenuMapper!!.deleteRoleMenuByRoleId(roleId)
        // 删除角色与部门关联
        roleDeptMapper!!.deleteRoleDeptByRoleId(roleId)
        return roleMapper!!.deleteRoleById(roleId)
    }

    /**
     * 批量删除角色信息
     *
     * @param roleIds 需要删除的角色ID
     * @return 结果
     */
    @Transactional
    override fun deleteRoleByIds(roleIds: Array<Long?>): Int {
        roleIds.forEach { roleId ->
            checkRoleAllowed(SysRole(roleId))
            checkRoleDataScope(roleId)
            val role = selectRoleById(roleId)
            assert(countUserRoleByRoleId(roleId) > 0) {
                throw ServiceException("${role.roleName}已分配,不能删除")
            }
        }
        // 删除角色与菜单关联
        roleMenuMapper!!.deleteRoleMenu(roleIds)
        // 删除角色与部门关联
        roleDeptMapper!!.deleteRoleDept(roleIds)
        return roleMapper!!.deleteRoleByIds(roleIds)
    }

    /**
     * 取消授权用户角色
     *
     * @param userRole 用户和角色关联信息
     * @return 结果
     */
    override fun deleteAuthUser(userRole: SysUserRole?): Int {
        return userRoleMapper!!.deleteUserRoleInfo(userRole)
    }

    /**
     * 批量取消授权用户角色
     *
     * @param roleId 角色ID
     * @param userIds 需要取消授权的用户数据ID
     * @return 结果
     */
    override fun deleteAuthUsers(roleId: Long?, userIds: Array<Long?>?): Int {
        return userRoleMapper!!.deleteUserRoleInfos(roleId, userIds)
    }

    /**
     * 批量选择授权用户角色
     *
     * @param roleId 角色ID
     * @param userIds 需要授权的用户数据ID
     * @return 结果
     */
    override fun insertAuthUsers(roleId: Long?, userIds: Array<Long?>): Int {
        // 新增用户与角色管理
        val list: MutableList<SysUserRole> = ArrayList()
        userIds.forEach {
            val ur = SysUserRole()
            ur.userId = it
            ur.roleId = roleId
            list.add(ur)
        }
        return userRoleMapper!!.batchUserRole(list)
    }
}
